package com.jl.sms.cdma;

import java.util.ArrayList;
import java.util.List;

import com.jl.sms.ISMSTPDU;
import com.jl.sms.cdma.BearerData.DisplayMode;
import com.jl.util.HexUtil;

public class CDMA implements ISMSTPDU {

	public static final int SMS_Point_to_Point = 0x00;
	public static final int SMS_Broadcast = 0x01;
	public static final int SMS_Acknowledge = 0x02;

	public static final int MSG_TYPE_Deliver = 0x01;
	public static final int MSG_TYPE_Submit = 0x02;

	public static final int DISPLAY_MODE_Not_Show = 0xE0;
	public static final int DISPLAY_MODE_Immediate = 0x00;
	public static final int DISPLAY_MODE_Mobile_Default = 0x40;
	public static final int DISPLAY_MODE_User_Invoke = 0x80;

	public static final int ADDRESS_Originating = 0x02;
	public static final int ADDRESS_Destination = 0x04;

	public static final int TELESERVICE_CMT_91 = 4096;
	public static final int TELESERVICE_CPT_95 = 4097;
	public static final int TELESERVICE_CMT_95 = 4098;
	public static final int TELESERVICE_VMN_95 = 4099;

	public static final int ENCODING_Octet = 0x00;
	public static final int ENCODING_Extended_Protocol_Message = 0x01;
	public static final int ENCODING_7bitASCII = 0x02;
	public static final int ENCODING_IA5 = 0x03;
	public static final int ENCODING_UNICODE = 0x04;
	public static final int ENCODING_Shift_JIS = 0x05;
	public static final int ENCODING_Korean = 0x06;
	public static final int ENCODING_Hebrew = 0x07;
	public static final int ENCODING_Latin = 0x08;
	public static final int ENCODING_GSM_7bitdefaultalphabet = 0x09;
	public static final int ENCODING_GSM_Data_Coding_Scheme = 0x0A;

	private List<Parameter> params = new ArrayList<Parameter>();
	private int smsType = SMS_Point_to_Point;
	private byte[] tpdu;

	public static class Builder {

		private Address address;
		private BearerData bd;
		private int msgType;
		private BearerData.MessageIdentifier msgID;
		private DisplayMode msgDisplayMode;
		private TeleserviceIdentifier teleserviceIdentifier = new TeleserviceIdentifier(
				CDMA.TELESERVICE_CMT_95);
		private byte[] data;
		private int encoding = CDMA.ENCODING_Octet;
		private Boolean headerIndFlag = null;

		/**
		 * 
		 * @param msgType
		 *            CDMA.MSG_TYPE_Deliver or MSG_TYPE_Submit
		 * @param data
		 */
		public Builder(int msgType, byte[] data) {
			this.msgType = msgType;
			this.data = data;
		}

		public Builder address(String address) {
			int type = CDMA.ADDRESS_Destination;
			if (msgType == CDMA.MSG_TYPE_Deliver) {
				type = CDMA.ADDRESS_Originating;
			}
			this.address = new Address(type, address);
			return this;
		}

		public Builder displayMode(int mode) {
			this.msgDisplayMode = new BearerData.DisplayMode(mode);
			return this;
		}

		public Builder teleservice(int teleID) {
			this.teleserviceIdentifier = new TeleserviceIdentifier(teleID);
			return this;
		}

		public Builder encoding(int type) {
			this.encoding = type;
			return this;
		}
		
		public Builder headerInd(boolean flag){
			this.headerIndFlag  = flag;
			return this;
		}

		public CDMA build() {
			if (address == null) {
				int type = CDMA.ADDRESS_Destination;
				if (msgType == CDMA.MSG_TYPE_Deliver) {
					type = CDMA.ADDRESS_Originating;
				}
				address = new Address(type, "123456789");
			}
			Parameter ud = new BearerData.UserData(encoding, data,
					msgType == CDMA.MSG_TYPE_Submit);

			boolean headerFlag = false;
			if(this.headerIndFlag != null){
				headerFlag = headerIndFlag;
			}else{
				if (encoding == CDMA.ENCODING_Octet) {
					headerFlag = true;
				}
			}

			msgID = new BearerData.MessageIdentifier(this.msgType, headerFlag);
			bd = new BearerData().addSubParameter(msgID)
					.addSubParameter(msgDisplayMode).addSubParameter(ud);

			return new CDMA(CDMA.SMS_Point_to_Point, teleserviceIdentifier,
					address, bd);
		}
	}

	public CDMA(int smsType, TeleserviceIdentifier p1, Address p2, BearerData p3) {
		this.smsType = smsType;
		params.add(p1);
		params.add(p2);
		params.add(p3);
	}

	public CDMA(byte[] tpdu) {
		this.tpdu = tpdu;
		this.smsType = tpdu[0];
		int index = 1;
		while(index < tpdu.length){
			addParameter(ParameterFactory.newInstance(tpdu, index));
			index += tpdu[index + 1] + 2;
		}
	}

	@Override
	public byte[] getTPDU() {

		if (this.tpdu != null) {
			return this.tpdu;
		}

		byte[] res = new byte[1];

		res[0] = (byte) smsType;

		for (Parameter one : params) {
			if (one == null) {
				continue;
			}
			res = HexUtil.contacByteArray(res, one.value());
		}
		return res;
	}
	
	public CDMA addParameter(Parameter param){
		this.params.add(param);
		return this;
	}
	
	
}
